package cn.com.lei.du.service.impl;

import cn.com.lei.du.entity.User;
import cn.com.lei.du.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import rx.Observable;
import rx.Subscriber;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public User getUser() {
        return restTemplate.getForEntity("http://EUREKA-CLIENT/user/getUser",User.class).getBody();
    }

    @Override
    public User getUserByName(String name) {
        log.info("mobile ribbon get user param------>");
        return restTemplate.getForEntity("http://EUREKA-CLIENT/user/getUserByName?name={1}",User.class,name).getBody();
    }

    @Override
    public User getUserByNameMap(String name) {
        Map<String,Object> map = new HashMap<>();
        map.put("name",name);
        log.info("mobile ribbon get user map------>");
        return restTemplate.getForEntity("http://EUREKA-CLIENT/user/getUserByName?name={name}",User.class,map).getBody();
    }

    @Override
    public User postUserByName(String name) {
        log.info("mobile ribbon post user param------>");
        return restTemplate.postForEntity("http://EUREKA-CLIENT/user/postUserByName?name={1}",null,User.class,name).getBody();
    }

    @Override
    public User postUserByNameMap(String name) {
        log.info("mobile ribbon post user map------>");
        Map<String,Object> map = new HashMap<>();
        map.put("name",name);
        return restTemplate.postForEntity("http://EUREKA-CLIENT/user/postUserByName?name={name}",null,User.class,map).getBody();
    }

    /**
     * 以requestbody的形式传递给服务
     */
    @Override
    @HystrixCommand(fallbackMethod = "errorMethod")
    public Object postUserByRequestBody(String name) {
        log.info("mobile ribbon post user requestBody------>");
        User user = new User();
        user.setName(name);
        return restTemplate.postForEntity("http://EUREKA-CLIENT/user/postUserRequestBody",user,User.class).getBody();
    }

    @Override
    @HystrixCommand(fallbackMethod = "asyErrorMethod")
    public Future<User> postUserByRequestBodyAsy(final String name) {
        return new AsyncResult<User>(){
            @Override
            public User invoke(){
                log.info("mobile ribbon post user requestBody asy------>");
                User user = new User();
                user.setName(name);
                return restTemplate.postForEntity("http://EUREKA-CLIENT/user/postUserRequestBody",user,User.class).getBody();
            }
        };
    }

    @Override
    @HystrixCommand
    public Observable<User> observe(final String name) {
        return Observable.unsafeCreate(new Observable.OnSubscribe<User>() {
            @Override
            public void call(Subscriber<? super User> observer) {
                try {
                    if (!observer.isUnsubscribed()) {
                        User user1 = new User();
                        user1.setName(name);
                        log.info("put in------>");
                        User user = restTemplate.postForEntity("http://EUREKA-CLIENT/user/postUserRequestBody", user1, User.class).getBody();
                        observer.onNext(user);
                        observer.onCompleted();
                    }
                } catch (Exception e) {

                }
            }
        });
    }

    public Object errorMethod(String name){
        Map<String,String> map  = new HashMap<>();
        map.put("error","time over");
        return map;
    }

    public User asyErrorMethod(String name){
        log.error("asy error ---->");
        User user = new User();
        user.setName(name);
        return user;
    }

}
